﻿using B.S.BaseData.Domain.Entities.RBAC;
using B.S.BaseData.Infrastructure.Helper;
using B.S.BaseData.Infrastructure.Implements;
using B.S.BaseData.Infrastructure.Interfaces;
using B.S.BaseData.ReadAPI.Utils;
using B.S.DataBase.EFCoreServiers.Dtos.Depts;
using B.S.DataBase.EFCoreServiers.IServices.Dtpes;
using B.S.DataBase.EFCoreServiers.IServices.Logs;
using B.S.DataBase.EFCoreServiers.IServices.Meetings;
using B.S.DataBase.EFCoreServiers.IServices.Permissions;
using B.S.DataBase.EFCoreServiers.IServices.Roles;
using B.S.DataBase.EFCoreServiers.IServices.Users;
using B.S.DataBase.EFCoreServiers.Services.Depts;
using B.S.DataBase.EFCoreServiers.Services.Logs;
using B.S.DataBase.EFCoreServiers.Services.Meetings;
using B.S.DataBase.EFCoreServiers.Services.Permissions;
using B.S.DataBase.EFCoreServiers.Services.Roles;
using B.S.DataBase.EFCoreServiers.Services.Users;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.ComponentModel.Design;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Text;
using Yitter.IdGenerator;

namespace B.S.BaseData.ReadAPI.Extensions
{
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 注册数据库
        /// </summary>
        /// <typeparam name="TDbContext"></typeparam>
        /// <param name="services"></param>
        /// <param name="connectionString"></param>
        /// <param name="enableSqlLog"></param>
        /// <returns></returns>
        public static IServiceCollection AddDbContextService<TDbContext>(this IServiceCollection services, string? connectionString, bool enableSqlLog) where TDbContext : DbContext
        {
            return services.AddDbContext<TDbContext>(builder =>
            {
                builder.UseSqlServer(connectionString!, action =>
                {
                    action.EnableRetryOnFailure(
                        10,
                        TimeSpan.FromSeconds(60),
                        null);
                }).EnableSensitiveDataLogging();
                if (enableSqlLog)
                    builder.UseLoggerFactory(LoggerFactory.Create(configure =>
                    {
                        configure
                            .AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information)
                            .AddConsole();
                    }));
            });
        }

        /// <summary>
        /// 注册JWT
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="builder"></param>
        public static void AddJwt(this IServiceCollection collection, WebApplicationBuilder builder)
        {
            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    //取出私钥
                    var secretByte = Encoding.UTF8.GetBytes(builder.Configuration["Authentication:SecretKey"]);
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        //验证发布者
                        ValidateIssuer = true,
                        ValidIssuer = builder.Configuration["Authentication:Issuer"],
                        //验证接收者
                        ValidateAudience = true,
                        ValidAudience = builder.Configuration["Authentication:Audience"],
                        //验证是否过期
                        ValidateLifetime = true,
                        //验证私钥
                        IssuerSigningKey = new SymmetricSecurityKey(secretByte)
                    };
                });
        }


        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddServices(this IServiceCollection services)
        {
            //仓储基类
            services.AddScoped(typeof(IBaseRepository<>), typeof(BaseRepository<>));

            //用户仓储
            services.AddScoped<IUserRepository, UserRepository>();
            //角色仓储
            services.AddScoped<IRoleRepository, RoleRepository>();
            //用户角色仓储
            services.AddScoped<IUserRoleRepository, UserRoleRepository>();
            //部门仓储
            services.AddScoped<IDepartmentRepository, DepartmentRepository>();
            //权限仓储
            services.AddScoped<IPermissionRepository, PermissionRepository>();
            //角色权限仓储
            services.AddScoped<IRolePermissionRepository, RolePermissionRepository>();
            //会议室仓储
            services.AddScoped<IMeetingRoomRepository, MeetingRoomRepository>();
            //会议室预约仓储
            services.AddScoped<IMeetingReservationRepository, MeetingReservationRepository>();
            //会议室审批仓储
            services.AddScoped<IMeetingApprovalRepository, MeetingApprovalRepository>();
            //日志仓储
            services.AddScoped<IOperationLogRepository, OperationLogRepository>();
           

            // Redis帮助类 - 使用非泛型实现
            services.AddSingleton<RedisHelpers>();

            //用户服务
            services.AddScoped<IUserServices, UserServices>();
            //角色服务
            services.AddScoped<IRoleServices, RoleServices>();
            //部门服务
            services.AddScoped<IDepartmentServices, DepartmentServices>();
            //权限服务
            services.AddScoped<IPermissionServices, PermissionServices>();
            //会议室服务
            services.AddScoped<IMeetingRoomServices, MeetingRoomServices>();
            //会议室预约服务
            services.AddScoped<IMeetingReservationServices, MeetingReservationServices>();
            //会议室审批服务
            services.AddScoped<IMeetingApprovalServices, MeetingApprovalServices>();
            //日志服务
            services.AddScoped<IOperationLogServices, OperationLogServices>();

            //生成自定义token
            services.AddScoped<TokenHelper>();
            //jwt生成
            services.AddSingleton<JwtSecurityTokenHandler>();

            services.AddAutoMapper(typeof(MapperProFiles));

            //注入中介者
            services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));

            //注入AutoMapper
            //services.AddAutoMapper(typeof(MappingProfile));

            //注入雪花ID
            YitIdHelper.SetIdGenerator(new IdGeneratorOptions());

            return services;
        }
    }
}
